package org.cqut.system.user.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lkx.util.ExcelUtil;
import org.cqut.system.clazz.domain.Clazz;
import org.cqut.system.clazz.mapper.ClazzMapper;
import org.cqut.system.user.domain.SysAuth;
import org.cqut.system.user.domain.SysRole;
import org.cqut.system.user.domain.SysUser;
import org.cqut.system.user.domain.SysUserRole;
import org.cqut.system.user.dto.UserExcelDTO;
import org.cqut.system.user.enumeration.StatusEnum;
import org.cqut.system.user.mapper.SysAuthMapper;
import org.cqut.system.user.mapper.SysRoleMapper;
import org.cqut.system.user.mapper.SysUserMapper;
import org.cqut.system.user.mapper.SysUserRoleMapper;
import org.cqut.system.user.service.SysUserService;
import org.cqut.system.user.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author XiAoXu
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService {
    private final SysUserMapper userMapper;

    private final SysAuthMapper authMapper;

    private final SysRoleMapper roleMapper;

    private final SysUserRoleMapper userRoleMapper;

    private final ClazzMapper clazzMapper;

    public SysUserServiceImpl(SysAuthMapper authMapper, SysRoleMapper roleMapper, SysUserMapper userMapper, SysUserRoleMapper userRoleMapper, ClazzMapper clazzMapper) {
        this.authMapper = authMapper;
        this.roleMapper = roleMapper;
        this.userMapper = userMapper;
        this.userRoleMapper = userRoleMapper;
        this.clazzMapper = clazzMapper;
    }


    @Override
    public List<SysAuth> findAuthByUserId(Long userId) {
        return authMapper.selectAuthListByUserId(userId);
    }

    @Override
    public List<SysRole> findRoleByUserId(Long userId) {
        return roleMapper.selectRoleListByUserId(userId);
    }

    @Override
    public SysUser findUserByUserName(String username) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public boolean editUser(UserVo userVo) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(userVo, sysUser);
        return updateById(sysUser);
    }

    @Override
    public boolean register(SysUser user) {
        //先判断是否存在此用户
        SysUser sysUser = findUserByUserName(user.getUsername());
        if (Objects.nonNull(sysUser)) {
            return false;
        }
        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
        int insert = userMapper.insert(user);
        //然后注册
        return insert == 1;
    }

    @Override
    public UserVo findUserVoByUsername(String username) {
        return userMapper.selectUserVoByUsername(username);
    }

    @Override
    public boolean updateAvatar(String path, String username) {
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("username", username);
        updateWrapper.set("avatar", path);
        return update(updateWrapper);
    }

    @Override
    public boolean updateNickname(UserVo userVo) {
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("username", userVo.getUsername());
        updateWrapper.set("nickname", userVo.getNickname());
        return update(updateWrapper);
    }


    @Override
    public boolean updatePasswordByUsername(SysUser user) {
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("username", user.getUsername());
        updateWrapper.set("password", new BCryptPasswordEncoder().encode(user.getPassword()));
        //判断是否是第一次修改
        if (user.getStatus() == 1) {
            updateWrapper.set("status", 0);
        }
        return update(updateWrapper);
    }

    @Override
    public String importUser(MultipartFile file) {
        StringBuffer sb = null;
        try {
            sb = new StringBuffer();
            List<UserExcelDTO> users = ExcelUtil.readXls(file.getBytes(), UserExcelDTO.class);
            for (int i = 0; i < users.size(); i++) {
                UserExcelDTO user = users.get(0);
                //1.检查学号是否为空
                if (user.getUsername().isEmpty()) {
                    sb.append("第").append(i + 1).append("行学号为空!");
                }
                //2.检查班级是否为空
                if (user.getClassName().isEmpty()) {
                    sb.append("第").append(i + 1).append("行班级为空!");
                }
                //3.检查邮箱是否为空
                if (user.getEmail().isEmpty()) {
                    sb.append("第").append(i + 1).append("行邮箱为空!");
                }
                //4.检查学号是否重复
                if (userNameIsExist(user.getUsername())) {
                    sb.append("第").append(i + 1).append("行学号重复!");
                }
                //5.检查邮箱是否重复
                if (emailIsExist(user.getEmail())) {
                    sb.append("第").append(i + 1).append("行邮箱重复!");
                }
                //6.检查班级是否存在
                if (classIsExist(user.getClassName())) {
                    sb.append("第").append(i + 1).append("行班级不存在!");
                }
            }
            if (sb.length() == 0) {
                //获取班级列表
                List<Clazz> cls = clazzMapper.selectList(null);

                int count = 0;
                for (UserExcelDTO userExcelDTO : users) {
                    //通过className找到classId
                    Long classId = cls.stream()
                            .filter(item -> Objects.equals(item.getClassName(), userExcelDTO.getClassName()))
                            .findFirst()
                            .orElse(new Clazz())
                            .getClassId();

                    SysUser user = new SysUser();
                    SysUserRole userRole = new SysUserRole();
                    user.setUsername(userExcelDTO.getUsername());
                    user.setEmail(userExcelDTO.getEmail());
                    user.setClassId(classId);
                    String username = userExcelDTO.getUsername();
                    //学号后六位
                    user.setPassword(new BCryptPasswordEncoder().encode(username.substring(username.length() - 6)));
                    count += userMapper.insert(user);

                    userRole.setUserId(user.getId());
                    userRole.setRoleId(2L);
                    userRoleMapper.insert(userRole);
                }
                if (count == users.size()) {
                    sb.append("成功插入").append(count).append("条数据");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Objects.requireNonNull(sb).toString();
    }

    @Override
    public IPage<UserVo> getStudentList(int page, int limit, String condition) {
        return userMapper.selectStudentList(new Page<>(page, limit), condition);
    }

    @Override
    public boolean disableAccount(String userId) {
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", userId);
        updateWrapper.set("status", StatusEnum.BANED.value);
        return update(updateWrapper);
    }

    @Override
    public boolean enableAccount(String userId) {
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", userId);
        updateWrapper.set("status", StatusEnum.NORMAL.value);
        return update(updateWrapper);
    }

    @Override
    public boolean insertStudent(SysUser user) {
        if (userNameIsExist(user.getUsername())) {
            return false;
        }
        String username = user.getUsername();
        user.setPassword(new BCryptPasswordEncoder().encode(username.substring(username.length() - 6)));
        userMapper.insert(user);

        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(2L);
        return userRoleMapper.insert(userRole) == 1;
    }

    @Override
    public boolean resetPassword(String userId) {
        SysUser user = getById(userId);
        String username = user.getUsername();
        user.setPassword(new BCryptPasswordEncoder().encode(username.substring(username.length() - 6)));
        return updateById(user);
    }

    private boolean userNameIsExist(String username) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return list(queryWrapper).size() != 0;
    }

    private boolean emailIsExist(String email) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", email);
        return list(queryWrapper).size() != 0;
    }

    private boolean classIsExist(String className) {
        QueryWrapper<Clazz> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("class_name", className);
        return clazzMapper.selectList(queryWrapper).size() == 0;
    }
}




